<!DOCTYPE HTML>
<html>
<head>
  <meta charset="utf-8">
  
  <title>art-template | H5教案</title>

  
  <meta name="author" content="John Doe">
  

  
  <meta name="description" content="页面渲染模式SSR(Server Side Rendering) ：传统的渲染方式，由服务端把渲染的完整的页面吐给客户端。这样减少了一次客户端到服务端的一次http请求，加快相应速度，一般用于首屏的性能优化。
SSR优点例如SEO–因为访问一个请求，返回的就是页面全部的HTML结构，包含所需要呈现的">
  

  
  
  <meta name="keywords" content="">
  

  <meta id="viewport" name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui">
  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta name="apple-mobile-web-app-status-bar-style" content="black">

  <meta property="og:title" content="art-template"/>

  <meta property="og:site_name" content="H5教案"/>

  
  <meta property="og:image" content="/ericxie-book/favicon.ico"/>
  

  <link href="/ericxie-book/favicon.ico" rel="icon">
  <link rel="alternate" href="/ericxie-book/atom.xml" title="H5教案" type="application/atom+xml">
  <link rel="stylesheet" href="/ericxie-book/css/style.css" media="screen" type="text/css">
<meta name="generator" content="Hexo 5.3.0"></head>


<body>
<div class="blog">
  <div class="content">

    <header>
  <div class="site-branding">
    <h1 class="site-title">
      <a href="/ericxie-book/">H5教案</a>
    </h1>
    <p class="site-description"></p>
  </div>
  <nav class="site-navigation">
    <ul>
      
    </ul>
  </nav>
</header>

    <main class="site-main posts-loop">
    <article>

  
    
    <h3 class="article-title"><span>art-template</span></h3>
    
  

  <div class="article-top-meta">
    <span class="posted-on">
      <a href="/ericxie-book/2021/01/30/art-template/" rel="bookmark">
        <time class="entry-date published" datetime="2021-01-30T03:09:47.000Z">
          2021-01-30
        </time>
      </a>
    </span>
  </div>


  

  <div class="article-content">
    <div class="entry">
      
        <h2 id="页面渲染模式"><a href="#页面渲染模式" class="headerlink" title="页面渲染模式"></a>页面渲染模式</h2><h3 id="SSR"><a href="#SSR" class="headerlink" title="SSR"></a>SSR</h3><p>(Server Side Rendering) ：传统的渲染方式，由服务端把渲染的完整的页面吐给客户端。这样减少了一次客户端到服务端的一次http请求，加快相应速度，一般用于首屏的性能优化。</p>
<h4 id="SSR优点"><a href="#SSR优点" class="headerlink" title="SSR优点"></a>SSR优点</h4><p>例如SEO–因为访问一个请求，返回的就是页面全部的HTML结构，包含所需要呈现的所有数据，于是例如搜索引擎或者爬虫的数据抓取；</p>
<p>目前使用MV*架构的项目，大都是前后端分离，数据都是动态生成，不利于SEO优化<br>利于首屏渲染性能高–首屏的页面加载来自于服务器，不依赖与服务端的接口请求再数据处理；</p>
<h4 id="SSR缺点"><a href="#SSR缺点" class="headerlink" title="SSR缺点"></a>SSR缺点</h4><p>性能全都依赖于服务器<br>前端界面开发可操作性不高</p>
<h3 id="CSR"><a href="#CSR" class="headerlink" title="CSR"></a>CSR</h3><p>CSR(Client Side Rendering)：是一种目前流行的渲染方式，它依赖的是运行在客户端的JS，用户首次发送请求只能得到小部分的指引性HTML代码。第二次请求将会请求更多包含HTML字符串的JS文件。</p>
<h4 id="CSR优点"><a href="#CSR优点" class="headerlink" title="CSR优点"></a>CSR优点</h4><p>FP最快<br>客户端体验较好，因为在数据没更新之前，页面框架和元素是可以在dom生成的</p>
<p>FP：仅有一个 div 根节点。以VUE为例，div#app 注册一个空的div<br>FCP：包含页面的基本框架，但没有数据内容。以VUE为例，每个template中的div框架，对应VUE生命周期的mounted<br>FMP：包含页面所有元素及数据。以VUE为例，通过接口更新到页面的数据后完整的页面展示；对应VUE的生命周期中的updated</p>
<p>简而言之，就是数据拼接HTML字符串这件事放在服务端还是客户端造成了两者区别。</p>
<h4 id="CSR缺点"><a href="#CSR缺点" class="headerlink" title="CSR缺点"></a>CSR缺点</h4><p>不利于SEO–爬虫数据不好爬呀~~<br>整体加载完速度慢</p>
<h3 id="两者有何不同"><a href="#两者有何不同" class="headerlink" title="两者有何不同"></a>两者有何不同</h3><p>服务器端渲染的优势在于首屏渲染速度块，简单来讲它不需要来回多次往返于客户端和服务端。但是其性能等众多因素会影响用户体验，比如说：网速，在线活跃人数，服务器的物理位置等等。而客户端渲染则和服务端渲染相反，因为多次和服务器的交互导致首屏加载速度慢。但一旦这些请求完成之后，用户和页面之间的交互时用户体验就会好很多。</p>
<p>用一个现实生活的例子来看：假如从超市买东西吃，以SSR的角度来看，你每次在超市买完随即吃完再走，每次饿了都需要出发去超市。而从CSR的角度来看，就是你从超市购买许多原材料再拿回家去自己煮，多了能放冰箱，这样每次肚子饿了就不需要每次都往超市跑，唯一麻烦一点在于你得花时间挑选食材。</p>
<h3 id="优化方案"><a href="#优化方案" class="headerlink" title="优化方案"></a>优化方案</h3><p>1、优化首屏加载，减少白屏时间，提升加载性能：<br>2、加速或减少HTTP请求损耗：使用CDN加载公用库，使用强缓存和协商缓存，使用域名收敛，小图片使用Base64代替，使用Get请求代替Post请求，设置 Access-Control-Max-Age 减少预检请求，页面内跳转其他域名或请求其他域名的资源时使用浏览器prefetch预解析等；<br>3、延迟加载：非重要的库、非首屏图片延迟加载，SPA的组件懒加载等；<br>4、减少请求内容的体积：开启服务器Gzip压缩，JS、CSS文件压缩合并，减少cookies大小，SSR直接输出渲染后的HTML等；<br>5、浏览器渲染原理：优化关键渲染路径，尽可能减少阻塞渲染的JS、CSS；<br>6、优化用户等待体验：白屏使用加载进度条、loading图、骨架屏代替等；</p>
<p>强缓存和协商缓存</p>
<p>强缓存是利用http头中的Expires和Cache-Control两个字段来控制的，用来表示资源的缓存时间<br>协商缓存：浏览器第一次请求一个资源的时候，服务器返回的header中会加上Last-Modify，Last-modify是一个时间标识该资源的最后修改时间；当浏览器再次请求该资源时，request的请求头中会包含If-Modify-Since，该值为缓存之前返回的Last-Modify。服务器收到If-Modify-Since后，根据资源的最后修改时间判断是否命中缓存；其中Etag：web服务器响应请求时，告诉浏览器当前资源在服务器的唯一标识</p>
<p>Access-Control-Max-Age：缓存可以被缓存的时间</p>
<p>SPA 只有一张Web页面的应用,是加载单个HTML页面并在用户与应用程序交互时动态更新该页面的Web应用程序，是指在浏览器中运行的应用，在使用期间不会重新加载页面。像所有的应用一样，它旨在帮助用户完成任务，比如“编写文档”或者“管理Web服务器”</p>
<p>域名发散<br>域名发散就是为了突破浏览器对于同一域名并发请求数的限制，使用域名发散为同一个服务申请多个域名，从而可以一定程度上提高并发量；当然，由于建立新的请求需要一定的代价，因此需要在域名发散与域名收敛间进行trade off，通常发散的域名个数为2-4个；</p>
<p>域名收敛<br>域名收敛就是将静态资源放在一个域名下不进行发散，这主要是为了适应移动端的发展需求；通常DNS是一个开销较大的操作，而移动端由于网络带宽和实时性、资源等的限制，这些开销对移动端的用户体验是致命的，因此需要进行域名收敛；</p>
<p>域名发散是pc端为了利用浏览器的多线程并行下载能力。而域名收敛多用与移动端，提高性能，因为dns解析是是从后向前迭代解析，如果域名过多性能会下降，增加DNS的解析开销。</p>
<p>DNS 预解析：浏览器会在加载网页时对网页中的域名进行解析缓存，这样在你单击当前网页中的连接时就无需进行DNS的解析，减少用户等待时间，提高用户体验。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;link rel=<span class="string">&quot;dns-prefetch&quot;</span> href=<span class="string">&quot;www.ytuwlg.iteye.com&quot;</span> /&gt;</span><br></pre></td></tr></table></figure>
<p>Gzip页面压缩，像服务器发送压缩文件，同时服务器需要设置解析</p>
<h4 id="简而言之，SSR强在首屏渲染。而CSR强在用户和页面多交互的场景"><a href="#简而言之，SSR强在首屏渲染。而CSR强在用户和页面多交互的场景" class="headerlink" title="简而言之，SSR强在首屏渲染。而CSR强在用户和页面多交互的场景"></a>简而言之，SSR强在首屏渲染。而CSR强在用户和页面多交互的场景</h4><h2 id="art介绍"><a href="#art介绍" class="headerlink" title="art介绍"></a>art介绍</h2><p>art-template 是一个简约、超快的模板引擎。<br>它采用作用域预声明的技术来优化模板渲染速度，从而获得接近 JavaScript 极限的运行性能，并且同时支持 NodeJS 和浏览器。</p>
<p>art-template 既可以用在前端，也可以用在后端<br>当CSR时前端直接使用art-template根据通信的数据渲染页面<br>当SSR时node也可以渲染生成静态页面或者将静态页面直接发回给前端</p>
<h3 id="CSR时前端通过art渲染页面"><a href="#CSR时前端通过art渲染页面" class="headerlink" title="CSR时前端通过art渲染页面"></a>CSR时前端通过art渲染页面</h3><h4 id="下载安装"><a href="#下载安装" class="headerlink" title="下载安装"></a>下载安装</h4><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm i art-template -S</span><br></pre></td></tr></table></figure>
<h4 id="引入和基础使用"><a href="#引入和基础使用" class="headerlink" title="引入和基础使用"></a>引入和基础使用</h4><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">&lt;!DOCTYPE html&gt;</span><br><span class="line">&lt;html lang=<span class="string">&quot;en&quot;</span>&gt;</span><br><span class="line">&lt;head&gt;</span><br><span class="line">    &lt;meta charset=<span class="string">&quot;UTF-8&quot;</span>&gt;</span><br><span class="line">    &lt;meta name=<span class="string">&quot;viewport&quot;</span> content=<span class="string">&quot;width=device-width, initial-scale=1.0&quot;</span>&gt;</span><br><span class="line">    &lt;title&gt;Document&lt;/title&gt;</span><br><span class="line">    &lt;script src=<span class="string">&quot;./node_modules/art-template/lib/template-web.js&quot;</span>&gt;&lt;/script&gt;</span><br><span class="line">&lt;/head&gt;</span><br><span class="line">&lt;body&gt;</span><br><span class="line">    &lt;div id=<span class="string">&quot;app&quot;</span>&gt;&lt;/div&gt;</span><br><span class="line">    &lt;script id=<span class="string">&quot;tp&quot;</span> <span class="built_in">type</span>=<span class="string">&quot;text/html&quot;</span>&gt;</span><br><span class="line">        &#123;&#123;<span class="keyword">if</span> user&#125;&#125;</span><br><span class="line">        &lt;h2&gt;&#123;&#123;user.name&#125;&#125;&lt;/h2&gt;</span><br><span class="line">        &lt;h2&gt;&#123;&#123;user.age&#125;&#125;&lt;/h2&gt;</span><br><span class="line">        &#123;&#123;/<span class="keyword">if</span>&#125;&#125;</span><br><span class="line">    &lt;/script&gt;</span><br><span class="line">    &lt;script&gt;</span><br><span class="line">        var user=&#123;name:<span class="string">&quot;xietian&quot;</span>,age:30&#125;;</span><br><span class="line">        document.querySelector(<span class="string">&quot;#app&quot;</span>).innerHTML=template(<span class="string">&quot;tp&quot;</span>,&#123;user:user&#125;);</span><br><span class="line">    &lt;/script&gt;</span><br><span class="line">&lt;/body&gt;</span><br><span class="line">&lt;/html&gt;</span><br></pre></td></tr></table></figure>
<h4 id="语法使用"><a href="#语法使用" class="headerlink" title="语法使用"></a>语法使用</h4><p>art分为两种语法，标准语法与原始语法。标准语法可以让模板易读写，而原始语法拥有强大的逻辑表达能力。</p>
<h5 id="输出"><a href="#输出" class="headerlink" title="输出"></a>输出</h5><p>标准语法</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">&#123;&#123;value&#125;&#125;</span><br><span class="line">&#123;&#123;data.key&#125;&#125;</span><br><span class="line">&#123;&#123;data[<span class="string">&#x27;key&#x27;</span>]&#125;&#125;</span><br><span class="line">&#123;&#123;a ? b : c&#125;&#125;</span><br><span class="line">&#123;&#123;a || b&#125;&#125;</span><br><span class="line">&#123;&#123;a + b&#125;&#125;</span><br></pre></td></tr></table></figure>
<p>原始语法</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">&lt;%= value %&gt;</span><br><span class="line">&lt;%= data.key %&gt;</span><br><span class="line">&lt;%= data[<span class="string">&#x27;key&#x27;</span>] %&gt;</span><br><span class="line">&lt;%= a ? b : c %&gt;</span><br><span class="line">&lt;%= a || b %&gt;</span><br><span class="line">&lt;%= a + b %&gt;</span><br></pre></td></tr></table></figure>
<p>模板一级特殊变量</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;%= <span class="variable">$data</span> %&gt;</span><br></pre></td></tr></table></figure>
<h5 id="原文输出"><a href="#原文输出" class="headerlink" title="原文输出"></a>原文输出</h5><p>标准语法</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&#123;&#123;@ value &#125;&#125;</span><br></pre></td></tr></table></figure>
<p>原始语法</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;%- value %&gt;</span><br></pre></td></tr></table></figure>
<p>原文输出语句不会对 HTML 内容进行转义处理，可能存在安全风险，请谨慎使用。</p>
<h5 id="条件"><a href="#条件" class="headerlink" title="条件"></a>条件</h5><p>标准语法</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&#123;&#123;<span class="keyword">if</span> value&#125;&#125; ... &#123;&#123;/<span class="keyword">if</span>&#125;&#125;</span><br><span class="line">&#123;&#123;<span class="keyword">if</span> v1&#125;&#125; ... &#123;&#123;<span class="keyword">else</span> <span class="keyword">if</span> v2&#125;&#125; ... &#123;&#123;/<span class="keyword">if</span>&#125;&#125;</span><br></pre></td></tr></table></figure>
<p>原始语法</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&lt;% <span class="keyword">if</span> (value) &#123; %&gt; ... &lt;% &#125; %&gt;</span><br><span class="line">&lt;% <span class="keyword">if</span> (v1) &#123; %&gt; ... &lt;% &#125; <span class="keyword">else</span> <span class="keyword">if</span> (v2) &#123; %&gt; ... &lt;% &#125; %&gt;</span><br></pre></td></tr></table></figure>
<h5 id="循环"><a href="#循环" class="headerlink" title="循环"></a>循环</h5><p>标准语法</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&#123;&#123;each target&#125;&#125;</span><br><span class="line">    &#123;&#123;<span class="variable">$index</span>&#125;&#125; &#123;&#123;<span class="variable">$value</span>&#125;&#125;</span><br><span class="line">&#123;&#123;/each&#125;&#125;</span><br></pre></td></tr></table></figure>
<p>原始语法</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&lt;% <span class="keyword">for</span>(var i = 0; i &lt; target.length; i++)&#123; %&gt;</span><br><span class="line">    &lt;%= i %&gt; &lt;%= target[i] %&gt;</span><br><span class="line">&lt;% &#125; %&gt;</span><br></pre></td></tr></table></figure>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">target 支持 array 与 object 的迭代，其默认值为 <span class="variable">$data</span>。</span><br><span class="line"><span class="variable">$value</span> 与 <span class="variable">$index</span> 可以自定义：&#123;&#123;each target <span class="variable">$val</span> <span class="variable">$key</span>&#125;&#125;。</span><br></pre></td></tr></table></figure>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"> &#123;&#123;each user <span class="variable">$key</span> <span class="variable">$val</span>&#125;&#125;</span><br><span class="line">    &lt;div&gt;&#123;&#123;<span class="variable">$key</span>&#125;&#125;:&#123;&#123;<span class="variable">$val</span>&#125;&#125;&lt;/div&gt;</span><br><span class="line">&#123;&#123;/each&#125;&#125;</span><br></pre></td></tr></table></figure>
<h5 id="变量"><a href="#变量" class="headerlink" title="变量"></a>变量</h5><p>标准语法</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&#123;&#123;<span class="built_in">set</span> temp = data.sub.content&#125;&#125;</span><br></pre></td></tr></table></figure>
<p>原始语法</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;% var temp = data.sub.content; %&gt;</span><br></pre></td></tr></table></figure>
<h3 id="SSR时Node中express通过art渲染页面"><a href="#SSR时Node中express通过art渲染页面" class="headerlink" title="SSR时Node中express通过art渲染页面"></a>SSR时Node中express通过art渲染页面</h3><h4 id="下载安装引入"><a href="#下载安装引入" class="headerlink" title="下载安装引入"></a>下载安装引入</h4><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm i express express-art-template -S</span><br></pre></td></tr></table></figure>
<h4 id="express中语法使用"><a href="#express中语法使用" class="headerlink" title="express中语法使用"></a>express中语法使用</h4><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line">const express=require(<span class="string">&quot;express&quot;</span>);</span><br><span class="line">var app=express();</span><br><span class="line">app.use(express.static(<span class="string">&quot;./&quot;</span>));//设置静态目录的</span><br><span class="line">app.engine(<span class="string">&#x27;art&#x27;</span>, require(<span class="string">&#x27;express-art-template&#x27;</span>));</span><br><span class="line"></span><br><span class="line">app.set(<span class="string">&quot;views options&quot;</span>,&#123;</span><br><span class="line">    debug:process.env.Node_ENV!==<span class="string">&#x27;production&#x27;</span></span><br><span class="line">&#125;);//// 启动模板引擎调试模式。如果为 <span class="literal">true</span>: &#123;cache:<span class="literal">false</span>, minimize:<span class="literal">false</span>, compileDebug:<span class="literal">true</span>&#125; </span><br><span class="line">cache 是否开启缓存 </span><br><span class="line">minimize 是否开启压缩。它会运行 htmlMinifier，将页面 HTML、CSS、CSS 进行压缩输出</span><br><span class="line">compileDebug 是否编译调试版</span><br><span class="line"></span><br><span class="line">compileDebug:<span class="literal">true</span>&#125;</span><br><span class="line">//默认文件夹是根目录，这里指定为view文件夹</span><br><span class="line">app.set(<span class="string">&quot;views&quot;</span>,path.join(__dirname,<span class="string">&quot;./view&quot;</span>));//设置views目录为view文件夹</span><br><span class="line">app.set(<span class="string">&quot;view engine&quot;</span>,<span class="string">&quot;art&quot;</span>);//设置view内容默认为art文件，渲染时可以不加扩展名</span><br><span class="line"></span><br><span class="line">app.get(<span class="string">&quot;/&quot;</span>,<span class="keyword">function</span>(req,res)&#123;</span><br><span class="line">    res.render(<span class="string">&quot;index.art&quot;</span>,&#123;data&#125;);</span><br><span class="line">&#125;)</span><br><span class="line">//app.set(<span class="string">&quot;view engine&quot;</span>,<span class="string">&quot;art&quot;</span>);  这个设置后就可以不用写扩展名</span><br><span class="line">app.get(<span class="string">&quot;/&quot;</span>,<span class="keyword">function</span>(req,res)&#123;</span><br><span class="line">    res.render(<span class="string">&quot;index&quot;</span>,&#123;data&#125;);</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p>基础语法与上面相同</p>
<h5 id="模板继承"><a href="#模板继承" class="headerlink" title="模板继承"></a>模板继承</h5><p>标准语法</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&#123;&#123;extend <span class="string">&#x27;./layout.art&#x27;</span>&#125;&#125;</span><br><span class="line">&#123;&#123;block <span class="string">&#x27;head&#x27;</span>&#125;&#125; ... &#123;&#123;/block&#125;&#125;</span><br></pre></td></tr></table></figure>
<p>原始语法</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&lt;% extend(<span class="string">&#x27;./layout.art&#x27;</span>) %&gt;</span><br><span class="line">&lt;% block(<span class="string">&#x27;head&#x27;</span>, <span class="function"><span class="title">function</span></span>()&#123; %&gt; ... &lt;% &#125;) %&gt;</span><br></pre></td></tr></table></figure>
<p>模板继承允许你构建一个包含你站点共同元素的基本模板“骨架”。范例：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line">&lt;!--layout.art--&gt;</span><br><span class="line">&lt;!doctype html&gt;</span><br><span class="line">&lt;html&gt;</span><br><span class="line">&lt;head&gt;</span><br><span class="line">    &lt;meta charset=<span class="string">&quot;utf-8&quot;</span>&gt;</span><br><span class="line">    &lt;title&gt;&#123;&#123;block <span class="string">&#x27;title&#x27;</span>&#125;&#125;My Site&#123;&#123;/block&#125;&#125;&lt;/title&gt;</span><br><span class="line"></span><br><span class="line">    &#123;&#123;block <span class="string">&#x27;head&#x27;</span>&#125;&#125;</span><br><span class="line">    &lt;link rel=<span class="string">&quot;stylesheet&quot;</span> href=<span class="string">&quot;main.css&quot;</span>&gt;</span><br><span class="line">    &#123;&#123;/block&#125;&#125;</span><br><span class="line">&lt;/head&gt;</span><br><span class="line">&lt;body&gt;</span><br><span class="line">    &#123;&#123;block <span class="string">&#x27;content&#x27;</span>&#125;&#125;&#123;&#123;/block&#125;&#125;</span><br><span class="line">&lt;/body&gt;</span><br><span class="line">&lt;/html&gt;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">&lt;!--index.art--&gt;</span><br><span class="line">&#123;&#123;extend <span class="string">&#x27;./layout.art&#x27;</span>&#125;&#125;</span><br><span class="line"></span><br><span class="line">&#123;&#123;block <span class="string">&#x27;title&#x27;</span>&#125;&#125;&#123;&#123;title&#125;&#125;&#123;&#123;/block&#125;&#125;</span><br><span class="line"></span><br><span class="line">&#123;&#123;block <span class="string">&#x27;head&#x27;</span>&#125;&#125;</span><br><span class="line">    &lt;link rel=<span class="string">&quot;stylesheet&quot;</span> href=<span class="string">&quot;custom.css&quot;</span>&gt;</span><br><span class="line">&#123;&#123;/block&#125;&#125;</span><br><span class="line"></span><br><span class="line">&#123;&#123;block <span class="string">&#x27;content&#x27;</span>&#125;&#125;</span><br><span class="line">&lt;p&gt;This is just an awesome page.&lt;/p&gt;</span><br><span class="line">&#123;&#123;/block&#125;&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">var express=require(<span class="string">&quot;express&quot;</span>);</span><br><span class="line">var app=express();</span><br><span class="line">app.use(express.static(<span class="string">&quot;./&quot;</span>));</span><br><span class="line">app.engine(<span class="string">&#x27;art&#x27;</span>, require(<span class="string">&#x27;express-art-template&#x27;</span>));</span><br><span class="line">app.get(<span class="string">&quot;/&quot;</span>,<span class="keyword">function</span>(req,res)&#123;</span><br><span class="line">   res.render(<span class="string">&quot;./index.art&quot;</span>,&#123;title:<span class="string">&quot;xietian&quot;</span>&#125;);</span><br><span class="line">&#125;)</span><br><span class="line">app.listen(4001);</span><br></pre></td></tr></table></figure>
<p>渲染 index.art 后，将自动应用布局骨架。</p>
<h5 id="子模板"><a href="#子模板" class="headerlink" title="子模板"></a>子模板</h5><p>标准语法</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&#123;&#123;include <span class="string">&#x27;./header.art&#x27;</span>&#125;&#125;</span><br><span class="line">&#123;&#123;include <span class="string">&#x27;./header.art&#x27;</span> data&#125;&#125;</span><br></pre></td></tr></table></figure>
<p>原始语法</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&lt;% include(<span class="string">&#x27;./header.art&#x27;</span>) %&gt;</span><br><span class="line">&lt;% include(<span class="string">&#x27;./header.art&#x27;</span>, data) %&gt;</span><br></pre></td></tr></table></figure>
<p>data 数默认值为 $data；标准语法不支持声明 object 与 array，只支持引用变量，而原始语法不受限制。<br>art-template 内建 HTML 压缩器，请避免书写 HTML 非正常闭合的子模板，否则开启压缩后标签可能会被意外“优化。</p>
<h5 id="过滤器"><a href="#过滤器" class="headerlink" title="过滤器"></a>过滤器</h5><p>注册过滤器</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">var express=require(<span class="string">&quot;express&quot;</span>);</span><br><span class="line">var template=require(<span class="string">&quot;art-template&quot;</span>);</span><br><span class="line">var app=express();</span><br><span class="line">app.use(express.static(<span class="string">&quot;./&quot;</span>));</span><br><span class="line">app.engine(<span class="string">&#x27;art&#x27;</span>, require(<span class="string">&#x27;express-art-template&#x27;</span>));</span><br><span class="line">template.defaults.imports.randomColor=<span class="function"><span class="title">function</span></span>()&#123;</span><br><span class="line">   var col=<span class="string">&quot;#&quot;</span>;</span><br><span class="line">   <span class="keyword">for</span>(var i=0;i&lt;6;i++)&#123;</span><br><span class="line">      col+=Math.floor(Math.random()*16).toString(16);</span><br><span class="line">   &#125;</span><br><span class="line">   <span class="built_in">return</span> col;</span><br><span class="line">&#125;</span><br><span class="line">template.defaults.imports.getSum=<span class="keyword">function</span>(a,b)&#123;</span><br><span class="line">  <span class="built_in">return</span> a+b;</span><br><span class="line">&#125;</span><br><span class="line">app.get(<span class="string">&quot;/&quot;</span>,<span class="keyword">function</span>(req,res)&#123;</span><br><span class="line">   res.render(<span class="string">&quot;./c.art&quot;</span>,&#123;data:<span class="string">&quot;xietian&quot;</span>&#125;);</span><br><span class="line">&#125;)</span><br><span class="line">app.listen(4001);</span><br></pre></td></tr></table></figure>
<p>过滤器函数第一个参数接受目标值。</p>
<p>标准语法</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">&#123;&#123;extend <span class="string">&#x27;./layout.art&#x27;</span>&#125;&#125;</span><br><span class="line">&#123;&#123;block <span class="string">&#x27;title&#x27;</span>&#125;&#125;&#123;&#123;data&#125;&#125; site&#123;&#123;/block&#125;&#125;</span><br><span class="line"> &#123;&#123;block <span class="string">&#x27;head&#x27;</span>&#125;&#125;</span><br><span class="line">    &lt;link rel=<span class="string">&quot;stylesheet&quot;</span> href=<span class="string">&quot;./views/b.css&quot;</span>&gt;</span><br><span class="line">&#123;&#123;/block&#125;&#125;</span><br><span class="line">&#123;&#123;block <span class="string">&#x27;content&#x27;</span>&#125;&#125;</span><br><span class="line"></span><br><span class="line">&lt;div style=<span class="string">&#x27;color:&#123;&#123;randomColor&#125;&#125;&#x27;</span>&#125;&gt;asdb&lt;/div&gt;</span><br><span class="line">&lt;div&gt;&#123;&#123;getSum(5,6)&#125;&#125;&lt;/div&gt;</span><br><span class="line">&#123;&#123;/block&#125;&#125;</span><br></pre></td></tr></table></figure>
<p>原始语法</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;%= <span class="variable">$imports</span>.dateFormat(<span class="variable">$imports</span>.getSum(5,6), <span class="string">&#x27;&#x27;</span>) %&gt;</span><br></pre></td></tr></table></figure>
<h3 id="根据数据生成静态页面"><a href="#根据数据生成静态页面" class="headerlink" title="根据数据生成静态页面"></a>根据数据生成静态页面</h3><p>CMS网站发布系统的原型</p>
<p>a.art</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">&lt;!DOCTYPE html&gt;</span><br><span class="line">&lt;html lang=<span class="string">&quot;en&quot;</span>&gt;</span><br><span class="line">&lt;head&gt;</span><br><span class="line">    &lt;meta charset=<span class="string">&quot;UTF-8&quot;</span>&gt;</span><br><span class="line">    &lt;meta name=<span class="string">&quot;viewport&quot;</span> content=<span class="string">&quot;width=device-width, initial-scale=1.0&quot;</span>&gt;</span><br><span class="line">    &lt;title&gt;&#123;&#123;block <span class="string">&#x27;title&#x27;</span>&#125;&#125;my site&#123;&#123;/block&#125;&#125;&lt;/title&gt;</span><br><span class="line">&lt;/head&gt;</span><br><span class="line">&lt;body&gt;</span><br><span class="line">    &lt;h1&gt;&#123;&#123;title&#125;&#125;&lt;/h1&gt;</span><br><span class="line">    &lt;img src=<span class="string">&#x27;&#123;&#123;imgSrc&#125;&#125;&#x27;</span>&gt;</span><br><span class="line">    &lt;div style=<span class="string">&#x27;color:&#123;&#123;randomColor&#125;&#125;&#x27;</span>&gt;</span><br><span class="line">        &#123;&#123;content&#125;&#125;</span><br><span class="line">    &lt;/div&gt;</span><br><span class="line">    &lt;ul&gt;</span><br><span class="line">        &#123;&#123;each list&#125;&#125;</span><br><span class="line">        &lt;li&gt;&#123;&#123;<span class="variable">$value</span>&#125;&#125;&lt;/li&gt;</span><br><span class="line">        &#123;&#123;/each&#125;&#125;</span><br><span class="line">    &lt;/ul&gt;</span><br><span class="line">&lt;/body&gt;</span><br><span class="line">&lt;html&gt;</span><br></pre></td></tr></table></figure>
<p>index.js</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line">var express=require(<span class="string">&quot;express&quot;</span>);</span><br><span class="line">var path=require(<span class="string">&quot;path&quot;</span>);</span><br><span class="line">var fs=require(<span class="string">&quot;fs&quot;</span>);</span><br><span class="line">var template=require(<span class="string">&quot;art-template&quot;</span>);</span><br><span class="line">var app=express();</span><br><span class="line">app.use(express.static(<span class="string">&quot;./&quot;</span>));</span><br><span class="line">app.engine(<span class="string">&#x27;art&#x27;</span>, require(<span class="string">&#x27;express-art-template&#x27;</span>));</span><br><span class="line">app.listen(4001);</span><br><span class="line"></span><br><span class="line">template.defaults.imports.randomColor=<span class="function"><span class="title">function</span></span>()&#123;</span><br><span class="line">   var col=<span class="string">&quot;#&quot;</span>;</span><br><span class="line">   <span class="keyword">for</span>(var i=0;i&lt;6;i++)&#123;</span><br><span class="line">      col+=Math.floor(Math.random()*16).toString(16);</span><br><span class="line">   &#125;</span><br><span class="line">   <span class="built_in">return</span> col;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">var arr=[</span><br><span class="line">   &#123;title:<span class="string">&quot;第一页&quot;</span>,imgSrc:<span class="string">&quot;./2.jpg&quot;</span>,content:<span class="string">&quot;这篇文章的内容是1...&quot;</span>,list:[1,2,3,4,5]&#125;,</span><br><span class="line">   &#123;title:<span class="string">&quot;第二页&quot;</span>,imgSrc:<span class="string">&quot;./3.jpg&quot;</span>,content:<span class="string">&quot;这篇文章的内容是2...&quot;</span>,list:[6,7,8,9]&#125;,</span><br><span class="line">   &#123;title:<span class="string">&quot;第三页&quot;</span>,imgSrc:<span class="string">&quot;./4.jpg&quot;</span>,content:<span class="string">&quot;这篇文章的内容是3...&quot;</span>,list:[1,2,45,2]&#125;,</span><br><span class="line">   &#123;title:<span class="string">&quot;第四页&quot;</span>,imgSrc:<span class="string">&quot;./5.jpg&quot;</span>,content:<span class="string">&quot;这篇文章的内容是4...&quot;</span>,list:[23,5,24,5]&#125;,</span><br><span class="line">   &#123;title:<span class="string">&quot;第五页&quot;</span>,imgSrc:<span class="string">&quot;./6.jpg&quot;</span>,content:<span class="string">&quot;这篇文章的内容是5...&quot;</span>,list:[2,4,5,21]&#125;,</span><br><span class="line">]</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> saveFile(html,i)&#123;</span><br><span class="line">   <span class="built_in">return</span> new Promise(resolve=&gt;&#123;</span><br><span class="line">      fs.writeFile(path.join(__dirname,<span class="string">&quot;./public/&quot;</span>+i+<span class="string">&quot;.html&quot;</span>),html,<span class="string">&quot;utf8&quot;</span>,<span class="function"><span class="title">function</span></span>()&#123;</span><br><span class="line">         resolve();</span><br><span class="line">      &#125;)</span><br><span class="line">   &#125;)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">async <span class="keyword">function</span> <span class="function"><span class="title">init</span></span>()&#123;</span><br><span class="line">   <span class="keyword">for</span>(var i=0;i&lt;arr.length;i++)&#123;</span><br><span class="line">     await saveFile(template(path.join(__dirname,<span class="string">&#x27;./views/a.art&#x27;</span>),arr[i]),i)</span><br><span class="line">   &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">init();</span><br></pre></td></tr></table></figure>
      
    </div>

  </div>

  <div class="article-footer">
    <div class="article-meta pull-left">

    

    

    </div>

    
  </div>
</article>

  






    </main>

    <footer class="site-footer">
  <p class="site-info">
    Proudly powered by <a href="https://hexo.io/" target="_blank">Hexo</a> and
    Theme by <a href="https://github.com/CodeDaraW/Hacker" target="_blank">Hacker</a>
    </br>
    
    &copy; 2021 John Doe
    
  </p>
</footer>
    
    
  </div>
</div>
</body>
</html>